package com.sojson.aspect;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;
import com.sojson.annotation.aspect.PointcutsWebBase;
import com.sojson.util.StringUtil;

/**
 * 参数空字符串转null切面
 * 
 * @author liu
 * @date 2021-05-18
 */
@Aspect
@Component
public class ParamEmptyToNullAspect extends PointcutsWebBase {

    /**
     * 请求处理之前和之后
     * 
     * @param pjp 切点
     * @return 接口返回的内容,可以拦截(这里如果不返回就等于接口不返回)
     * @throws Throwable
     */
    @Around(POINTCUT_GET)
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        // 获取所有参数对象
        Object[] args = pjp.getArgs();
        for (int i = 0; i < args.length; i++) {
            // arg为所有参数合成的对象
            Object arg = args[i];
            if (arg == null) {
                continue;
            }
            // 将这个对象参数为空字符串的值转为null
            args[i] = emptyToNull(arg, arg.getClass());
        }

        // 继续执行下一个切面
        return pjp.proceed(args);
    }

    /**
     * 将对象的空字符串转为null
     * 
     * @param obj
     * @return
     * @throws Exception
     */
    private static Object emptyToNull(Object obj, Class<?> clazz) throws Exception {
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            Object value = field.get(obj);
            if ("".equals(value)) {
                field.set(obj, null);
            }
        }

        Class<?> superclass = clazz.getSuperclass();
        if (StringUtil.isBlankObject(superclass)) {
            return obj;
        }
        return emptyToNull(obj, superclass);
    }

    /**
     * 将对象的空字符串转为null
     * 
     * @param obj
     * @param clazz
     * @return
     * @throws Exception 
     */
    @SuppressWarnings("unused")
    private static Object emptyToNullTwo(Object obj, Class<?> clazz) throws Exception {
        return JSONObject.parseObject(JSONObject.toJSONString(objectToMap(obj, clazz)), clazz);
    }

    /**
     * 将对象转为Map集合,并且将空字符串转为null
     * 
     * @param obj
     * @return
     * @throws Exception
     */
    private static Map<String, Object> objectToMap(Object obj, Class<?> clazz) throws Exception {
        Map<String, Object> map = new HashMap<>();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            if (value != null && !"".equals(value)) {
                map.put(fieldName, value);
            }
        }
        return map;
    }

}